<template>
  <div class="admin-page admin-user">
    <div class="page-header">
      <h1>用户管理</h1>
      <div class="actions">
        <el-button type="success" @click="downloadTemplate" v-if="canCreateEditUser">
          <el-icon><Download /></el-icon> 下载模板
        </el-button>
        <el-button type="warning" @click="showImportDialog" v-if="canCreateEditUser">
          <el-icon><Upload /></el-icon> 批量导入
        </el-button>
        <el-button type="primary" @click="openUserDialog(null)" v-if="canCreateEditUser">
          <el-icon><Plus /></el-icon> 新增用户
        </el-button>
      </div>
    </div>
    
    <el-card class="table-card">
      <div class="filter-container">
        <el-form :inline="true" class="filter-form">
          <el-form-item label="用户名">
            <el-input v-model="filters.name" placeholder="请输入用户名" clearable></el-input>
          </el-form-item>
          <el-form-item label="角色">
            <el-select v-model="filters.role" placeholder="请选择角色" clearable>
              <el-option label="管理员" value="admin"></el-option>
              <el-option label="部系领导" value="departmentHead"></el-option>
              <el-option label="教研室领导" value="researchHead"></el-option>
              <el-option label="教师" value="teacher"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="searchUsers">搜索</el-button>
            <el-button @click="resetFilters">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      
      <el-table
        v-loading="loading"
        :data="filteredUsers"
        border
        stripe
        style="width: 100%"
      >
        <el-table-column prop="id" label="用户ID" width="100" resizable></el-table-column>
        <el-table-column prop="username" label="登录名" min-width="120" resizable></el-table-column>
        <el-table-column prop="name" label="用户姓名" min-width="120" resizable></el-table-column>
        <el-table-column label="角色" min-width="150" resizable>
          <template #default="scope">
            <el-tag 
              v-for="role in scope.row.roles" 
              :key="role.id" 
              class="role-tag"
              :type="getRoleTagType(role.name)"
            >
              {{ getRoleDisplayName(role.name) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="部门" min-width="120" resizable>
          <template #default="scope">
            {{ scope.row.departmentName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="300" resizable>
          <template #default="scope">
            <el-button size="small" type="primary" @click="openUserDialog(scope.row)" v-if="canCreateEditUser">
              <el-icon><Edit /></el-icon> 编辑
            </el-button>
            <el-button size="small" type="warning" @click="resetPassword(scope.row)" v-if="canCreateEditUser">
              <el-icon><RefreshLeft /></el-icon> 重置密码
            </el-button>
            <el-button size="small" type="danger" @click="deleteUser(scope.row)" v-if="canCreateEditUser">
              <el-icon><Delete /></el-icon> 删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <div class="pagination-container">
        <el-pagination
          background
          layout="total, prev, pager, next, jumper"
          :total="total"
          :page-size="pageSize"
          :current-page="currentPage"
          @current-change="handlePageChange"
        ></el-pagination>
      </div>
    </el-card>
    
    <!-- 用户编辑对话框 -->
    <el-dialog
      :title="isEdit ? '编辑用户' : '新增用户'"
      v-model="dialogVisible"
      width="500px"
      append-to-body
      @close="handleDialogClose"
    >
      <el-form :model="userForm" :rules="rules" ref="userFormRef" label-width="80px">
        <el-form-item label="登录名" prop="username">
          <el-input v-model="userForm.username" placeholder="请输入登录名"></el-input>
        </el-form-item>
        <el-form-item label="姓名" prop="name">
          <el-input v-model="userForm.name" placeholder="请输入姓名"></el-input>
        </el-form-item>
        <el-form-item label="角色" prop="roleIds">
          <el-select v-model="userForm.roleIds" placeholder="请选择角色" multiple>
            <el-option 
              v-for="role in roles" 
              :key="role.id" 
              :label="role.description" 
              :value="role.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="部门" prop="departmentId">
          <el-select v-model="userForm.departmentId" placeholder="请选择部门">
            <el-option 
              v-for="dept in departments" 
              :key="dept.id" 
              :label="dept.name" 
              :value="dept.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="!isEdit" label="密码" prop="password">
          <el-input type="password" v-model="userForm.password" placeholder="请输入密码"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitUserForm" :loading="submitting">确定</el-button>
      </template>
    </el-dialog>

    <!-- 批量导入对话框 -->
    <el-dialog
      v-model="importDialogVisible"
      title="批量导入用户"
      width="50%"
      :close-on-click-modal="false"
    >
      <div class="import-content">
        <el-alert
          title="导入说明"
          type="info"
          :closable="false"
          show-icon
        >
          <template #default>
            <p>1. 请先下载模板文件，按照模板格式填写用户信息</p>
            <p>2. <span style="color: red; font-weight: bold;">必填字段</span>：用户名、姓名、密码</p>
            <p>3. <span style="color: green; font-weight: bold;">可选字段</span>：部门名称、角色、启用状态</p>
            <p>4. 用户名必须唯一，部门名称必须在系统中存在</p>
            <p>5. 角色可选：管理员、部系领导、教研室领导、教师、其他</p>
            <p>6. 多个角色用逗号分隔，如：部系领导,教师</p>
            <p>7. 启用状态填写'是'或'否'，默认为'是'</p>
            <p>8. 如有数据错误，将不会保存任何数据，请修正后重新导入</p>
          </template>
        </el-alert>

        <el-upload
          ref="uploadRef"
          class="upload-area"
          drag
          :auto-upload="false"
          :on-change="handleFileChange"
          :file-list="fileList"
          accept=".xlsx,.xls"
          :limit="1"
        >
          <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
          <div class="el-upload__text">
            将文件拖到此处，或<em>点击上传</em>
          </div>
          <template #tip>
            <div class="el-upload__tip">
              只能上传 Excel 文件，且文件大小不超过 10MB
            </div>
          </template>
        </el-upload>

        <div v-if="importResult" class="import-result">
          <el-alert
            :title="importResult.message"
            :type="importResult.success ? 'success' : 'error'"
            :closable="false"
            show-icon
          >
            <template #default>
              <p v-if="importResult.success">
                成功导入 {{ importResult.data?.successCount || 0 }} 条用户记录
              </p>
              <p v-if="importResult.data?.failureCount > 0">
                失败 {{ importResult.data.failureCount }} 条记录
              </p>
              <div v-if="importResult.data?.errors?.length > 0" class="error-details">
                <p><strong>错误详情：</strong></p>
                <div class="error-content">
                  <div v-for="(error, index) in importResult.data.errors" :key="index" class="error-item">
                    <pre>{{ error }}</pre>
                  </div>
                </div>
              </div>
            </template>
          </el-alert>
        </div>
      </div>

      <template #footer>
        <el-button @click="cancelImport">取消</el-button>
        <el-button type="primary" @click="handleImport" :loading="importing" :disabled="!selectedFile">
          导入
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ref, onMounted, computed, reactive, nextTick } from "vue";
import { getAllUsers, deleteUser as deleteUserApi, createUser, updateUser, resetUserPassword, importUsers, downloadUserTemplate } from "@/api/user";
import { roleApi } from "@/api/base-data";
import { departmentApi } from "@/api/base-data";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Edit, Delete, RefreshLeft, Download, Upload, UploadFilled } from "@element-plus/icons-vue";
import { useUserStore } from "@/stores/user";
import { useRouter } from "vue-router";
import { PermissionChecker } from "@/utils/permission";

export default {
  components: {
    Plus,
    Edit,
    Delete,
    RefreshLeft
  },
  setup() {
    const userStore = useUserStore();
    const router = useRouter();
    
    // 检查权限
    const canManageUsers = computed(() => 
      PermissionChecker.hasRoles(['ROLE_ADMIN', 'ROLE_DEPARTMENT_HEAD', 'ROLE_RESEARCH_HEAD'])
    );
    const canCreateEditUser = computed(() => 
      PermissionChecker.hasRoles(['ROLE_ADMIN'])
    );
    
    // 如果没有管理用户的权限，重定向到403页面
    if (!canManageUsers.value) {
      ElMessage.error("您没有权限访问用户管理页面");
      router.push("/403");
      return {};
    }
    
    const users = ref([]);
    const roles = ref([]);
    const departments = ref([]);
    const loading = ref(false);
    const submitting = ref(false);
    const dialogVisible = ref(false);
    const userFormRef = ref(null);
    
    // 分页相关
    const currentPage = ref(1);
    const pageSize = ref(10);
    const total = ref(0);
    
    // 筛选条件
    const filters = reactive({
      name: "",
      role: ""
    });
    
    // 用户表单
    const userForm = reactive({
      id: "",
      username: "",
      name: "",
      roleIds: [],
      departmentId: null,
      password: ""
    });

    // 导入相关状态
    const importDialogVisible = ref(false);
    const importing = ref(false);
    const selectedFile = ref(null);
    const fileList = ref([]);
    const importResult = ref(null);
    const uploadRef = ref(null);
    
    // 强制重置表单的方法
    const forceResetForm = () => {
      userForm.id = "";
      userForm.username = "";
      userForm.name = "";
      userForm.roleIds = [];
      userForm.departmentId = null;
      userForm.password = "";
    };
    
    const isEdit = computed(() => !!userForm.id);
    
    // 表单验证规则
    const rules = {
      username: [
        { required: true, message: "请输入登录名", trigger: "blur" },
        { min: 3, max: 20, message: "长度在 3 到 20 个字符", trigger: "blur" }
      ],
      name: [
        { required: true, message: "请输入姓名", trigger: "blur" }
      ],
      roleIds: [
        { required: true, message: "请选择角色", trigger: "change" }
      ],
      departmentId: [
        { required: true, message: "请选择部门", trigger: "change" }
      ],
      password: [
        { required: true, message: "请输入密码", trigger: "blur", validator: (rule, value, callback) => {
          if (!isEdit.value && !value) {
            callback(new Error("请输入密码"));
          } else {
            callback();
          }
        }}
      ]
    };

    const fetchUsers = async () => {
      loading.value = true;
      try {
        // 构建查询参数，包括分页和过滤条件
        const params = {
          page: currentPage.value - 1, // 后台从0开始
          size: pageSize.value
        }

        // 添加搜索条件
        if (filters.name?.trim()) {
          params.username = filters.name.trim()
        }
        if (filters.role) {
          params.role = filters.role
        }

        const response = await getAllUsers(params);
        users.value = response.content || [];
        total.value = response.totalElements || 0;
      } catch (error) {
        console.error("获取用户列表失败:", error);
        ElMessage.error("获取用户列表失败");
      } finally {
        loading.value = false;
      }
    };
    
    const fetchRoles = async () => {
      try {
        roles.value = await roleApi.getAllRoles();
      } catch (error) {
        console.error("获取角色列表失败:", error);
        ElMessage.error("获取角色列表失败");
      }
    };
    
    const fetchDepartments = async () => {
      try {
        departments.value = await departmentApi.getAllDepartments();
      } catch (error) {
        console.error("获取部门列表失败:", error);
        ElMessage.error("获取部门列表失败");
      }
    };
    
    // 由于改为后台分页，直接返回users数据
    const filteredUsers = computed(() => {
      return users.value;
    });
    
    // 搜索用户 - 重新获取数据
    const searchUsers = () => {
      currentPage.value = 1;
      fetchUsers();
    };
    
    // 重置筛选条件 - 重新获取数据
    const resetFilters = () => {
      filters.name = "";
      filters.role = "";
      currentPage.value = 1;
      fetchUsers();
    };
    
    // 处理页码变化 - 重新获取数据
    const handlePageChange = (page) => {
      currentPage.value = page;
      fetchUsers();
    };
    
    // 打开用户编辑对话框
    const openUserDialog = async (user) => {
      // 先强制重置表单数据
      forceResetForm();
      
      if (user) {
        // 编辑模式：填充现有数据
        userForm.id = user.id;
        userForm.username = user.username;
        userForm.name = user.name;
        userForm.roleIds = user.roles ? user.roles.map(role => role.id) : [];
        userForm.departmentId = user.departmentId || null;
      }
      
      dialogVisible.value = true;
      
      // 使用 nextTick 确保对话框完全渲染后再清除验证状态
      await nextTick();
      if (userFormRef.value) {
        userFormRef.value.clearValidate();
      }
    };
    
    // 重置用户表单
    const resetUserForm = async () => {
      Object.assign(userForm, {
        id: "",
        username: "",
        name: "",
        roleIds: [],
        departmentId: null,
        password: ""
      });
      
      // 使用 nextTick 确保数据绑定完成后再重置表单验证
      await nextTick();
      if (userFormRef.value) {
        userFormRef.value.resetFields();
        userFormRef.value.clearValidate();
      }
    };
    
    // 提交用户表单
    const submitUserForm = async () => {
      if (!userFormRef.value) return;
      
      try {
        await userFormRef.value.validate();
        submitting.value = true;
        
        // 准备提交数据，转换成后端期望的格式
        const userData = {
          id: userForm.id,
          username: userForm.username,
          name: userForm.name,
          password: userForm.password,
          enabled: true,
          departmentId: userForm.departmentId || null,
          roles: userForm.roleIds.map(id => ({ id }))
        };
        
        if (isEdit.value) {
          await updateUser(userForm.id, userData);
          ElMessage.success("更新用户成功");
        } else {
          await createUser(userData);
          ElMessage.success("创建用户成功");
        }
        
        dialogVisible.value = false;
        fetchUsers();
      } catch (error) {
        console.error("提交用户表单失败:", error);
        ElMessage.error("操作失败: " + (error.message || "未知错误"));
      } finally {
        submitting.value = false;
      }
    };

    // 处理对话框关闭
    const handleDialogClose = async () => {
      // 对话框关闭时强制重置表单数据
      forceResetForm();
      
      // 使用 nextTick 确保数据绑定完成后再清除验证状态
      await nextTick();
      if (userFormRef.value) {
        userFormRef.value.clearValidate();
      }
    };

    // 删除用户
    const deleteUser = async (user) => {
      try {
        await ElMessageBox.confirm(`确定要删除用户 ${user.name} 吗？`, "警告", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        });
        
        await deleteUserApi(user.id);
        ElMessage.success("删除成功");
        fetchUsers();
      } catch (error) {
        if (error !== "cancel") {
          console.error("删除用户失败:", error);
          ElMessage.error(`删除用户失败: ${error.message || '未知错误'}`);
        }
      }
    };
    
    // 重置用户密码
    const resetPassword = async (user) => {
      try {
        await ElMessageBox.confirm(`确定要重置用户 ${user.name} 的密码吗？重置后的密码将为：123456`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        });
        
        await resetUserPassword(user.id);
        ElMessage.success(`用户 ${user.name} 的密码已重置为：123456`);
      } catch (error) {
        if (error !== "cancel") {
          console.error("重置密码失败:", error);
          ElMessage.error("重置密码失败");
        }
      }
    };
    
    // 获取角色显示名称
    const getRoleDisplayName = (roleName) => {
      switch (roleName) {
        case 'ROLE_ADMIN': return '管理员';
        case 'ROLE_DEPARTMENT_HEAD': return '部系领导';
        case 'ROLE_RESEARCH_HEAD': return '教研室领导';
        case 'ROLE_TEACHER': return '教师';
        default: return roleName;
      }
    };
    
    // 获取角色标签类型
    const getRoleTagType = (roleName) => {
      switch (roleName) {
        case 'ROLE_ADMIN': return 'danger';
        case 'ROLE_DEPARTMENT_HEAD': return 'warning';
        case 'ROLE_RESEARCH_HEAD': return 'success';
        case 'ROLE_TEACHER': return 'info';
        default: return 'primary';
      }
    };

    // 下载用户导入模板
    const downloadTemplate = async () => {
      try {
        const response = await downloadUserTemplate();
        // 对于blob响应，API返回的是完整的response对象，需要访问response.data
        const blob = new Blob([response.data], { 
          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
        });
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = 'user_import_template.xlsx';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        window.URL.revokeObjectURL(url);
        ElMessage.success('模板下载成功');
      } catch (error) {
        console.error('下载模板失败:', error);
        ElMessage.error('下载模板失败');
      }
    };

    // 显示导入对话框
    const showImportDialog = () => {
      importDialogVisible.value = true;
      importResult.value = null;
      selectedFile.value = null;
      fileList.value = [];
    };

    // 处理文件选择
    const handleFileChange = (file) => {
      selectedFile.value = file.raw;
      importResult.value = null;
    };

    // 处理用户导入
    const handleImport = async () => {
      if (!selectedFile.value) {
        ElMessage.warning('请选择要导入的文件');
        return;
      }

      importing.value = true;
      try {
        const response = await importUsers(selectedFile.value);
        
        // 从响应中提取数据
        const data = response.data || response || {};
        const successCount = data.successCount || 0;
        const failureCount = data.failureCount || 0;
        const errors = data.errors || [];
        
        if (failureCount > 0) {
          // 有错误，显示错误信息
          importResult.value = {
            success: false,
            message: '导入失败，请检查错误信息',
            data: {
              successCount: successCount,
              failureCount: failureCount,
              errors: errors
            }
          };
        } else {
          // 导入成功
          importResult.value = {
            success: true,
            message: `成功导入 ${successCount} 条用户记录`,
            data: {
              successCount: successCount,
              failureCount: 0,
              errors: []
            }
          };
          // 刷新用户列表
          await fetchUsers();
        }
      } catch (error) {
        console.error('导入失败:', error);
        let errorMessage = '未知错误';
        let errorDetails = [];
        
        if (error.response?.data) {
          const responseData = error.response.data;
          // 检查响应结构
          if (responseData.code && responseData.code !== 200) {
            // 错误响应
            errorMessage = responseData.message || '导入失败';
            if (responseData.data?.error) {
              // 详细错误信息在data.error中
              errorDetails = [responseData.data.error];
            } else {
              errorDetails = [errorMessage];
            }
          } else if (responseData.message) {
            // 旧格式兼容
            errorMessage = responseData.message;
            errorDetails = [responseData.message];
          }
        } else {
          errorMessage = error.message || '网络错误';
          errorDetails = [errorMessage];
        }
        
        importResult.value = {
          success: false,
          message: errorMessage,
          data: { errors: errorDetails }
        };
      } finally {
        importing.value = false;
      }
    };

    // 取消导入
    const cancelImport = () => {
      importDialogVisible.value = false;
      selectedFile.value = null;
      fileList.value = [];
      importResult.value = null;
      if (uploadRef.value) {
        uploadRef.value.clearFiles();
      }
    };

    onMounted(async () => {
      await Promise.all([fetchUsers(), fetchRoles(), fetchDepartments()]);
    });

    return {
      users,
      filteredUsers,
      roles,
      departments,
      loading,
      filters,
      currentPage,
      pageSize,
      total,
      userForm,
      userFormRef,
      rules,
      dialogVisible,
      submitting,
      isEdit,
      canManageUsers,
      canCreateEditUser,
      searchUsers,
      resetFilters,
      handlePageChange,
      openUserDialog,
      submitUserForm,
      deleteUser,
      getRoleDisplayName,
      getRoleTagType,
      resetPassword,
      handleDialogClose,
      forceResetForm,
      // 导入相关
      importDialogVisible,
      importing,
      selectedFile,
      fileList,
      importResult,
      uploadRef,
      downloadTemplate,
      showImportDialog,
      handleFileChange,
      handleImport,
      cancelImport
    };
  }
};
</script>

<style scoped>
.admin-user {
  padding: 0;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.page-header h1 {
  font-size: 22px;
  font-weight: 600;
  color: #303133;
  margin: 0;
}

.actions {
  margin-left: auto;
}

.table-card {
  margin-bottom: 20px;
}

.filter-container {
  margin-bottom: 20px;
}

.filter-form {
  display: flex;
  flex-wrap: wrap;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.role-tag {
  margin-right: 5px;
  margin-bottom: 5px;
}

:deep(.el-dialog__body) {
  padding-top: 10px;
}

:deep(.el-dialog__footer) {
  padding-top: 0;
}

/* 导入对话框样式 */
.import-content {
  padding: 10px 0;
}

.upload-area {
  margin: 20px 0;
}

.import-result {
  margin-top: 20px;
}

.error-details {
  margin-top: 10px;
}

.error-content {
  margin: 5px 0;
  max-height: 300px;
  overflow-y: auto;
}

.error-item {
  margin-bottom: 10px;
}

.error-item pre {
  background-color: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 4px;
  padding: 12px;
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  color: #dc2626;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 13px;
  line-height: 1.5;
}
</style>
